/************************************
 * Package: RGcpp					*
 * Authors: Rui Eduardo Gouveia Gil	*
 * Date: 2010						*
 ************************************/
#ifndef __RGCPP_PRIORITYQUEUE_H__
#define __RGCPP_PRIORITYQUEUE_H__

#include <deque>
#include <queue>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>

namespace rgcpp
{

template <class Type>
class PriorityQueue
{
	private:
		bool running;
		boost::mutex mut;
		boost::mutex io_mutex;
		boost::condition_variable cond;
		std::priority_queue<Type,std::deque<Type>,std::less<Type> > queue;

	public:
		PriorityQueue()
		{
			running = true;
		}

		~PriorityQueue()
		{

		}

		void release()
		{
			running = false;
			cond.notify_all();
		}

		void addObject(Type obj)
		{
			boost::mutex::scoped_lock lock(mut);
			queue.push(obj);
			cond.notify_one();
		}

		Type getObject()
		{
			boost::mutex::scoped_lock lock(mut);

			if(!running) return Type();

			while(!queue.size() && running)
				cond.wait(lock);

			if(!running) return Type();

			Type obj = queue.top();
			queue.pop();

			return obj;
		}

		int size()
		{
			boost::mutex::scoped_lock lock(mut);
			return queue.size();
		}
};

}

#endif
